// go中如何实现一个"多态"?
package main

import (
	"fmt"
)

type Animal interface {
	speak() string
}

type Cat struct{}

func (p *Cat) speak() string {
	return "喵喵"
}

type Dog struct{}

type BigDog struct {
	Dog
}

func (p *Dog) speak() string {
	return "汪汪"
}
func (p BigDog) speak() string {
	return "大狗汪汪"
}

func output(p Animal) {
	fmt.Printf("%T %v\n", p, p.speak())
}

func main() {
	cat := &Cat{}   //第一种写法
	dog := new(Dog) //第二种写法
	bigDog := &BigDog{
		Dog{},
	}

	output(cat)    //*main.Cat 喵喵
	output(dog)    //*main.Dog 汪汪
	output(bigDog) //*main.BigDog 大狗汪汪
	println()

	//指针用 * 表示
	var point *Cat = &Cat{}
	var struct1 Cat = *point     //解引用，得到结构体
	fmt.Println(struct1.speak()) //输出:喵喵
	var nilCat *Cat              // 只是声明了，但是没有使用
	fmt.Println(nilCat == nil)   //输出:true
	println()
}
